# This file is part of the AutoMAT distribution (https://bitbucket.com/mahomaho/AutoMAT).
# Copyright (c) 2021 Mattias Holmqvist.
# 
# AutoMAT is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# 
# AutoMAT is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
# 
# You should have received a copy of the GNU General Public License
# along with AutoMAT.  If not, see <https://www.gnu.org/licenses/>.

import os as _os

_loaded={}
_deleted={}

class File:
	_synonym=None
	def __init__(self,file,abspath):
		self._file=file
		self._abspath=abspath
		self._modified=False
		if _os.access(self._abspath, _os.W_OK):
			self._readonly = False
		elif _os.access(self._abspath, _os.F_OK):
			# file exists but is not writeable
			self._readonly = True
		elif _os.access(_os.path.dirname(self._abspath), _os.W_OK):
			# file does not exists but dir is writeable
			self._readonly = False
		else:
			# file does not exists and dir is not writeable
			self._readonly = True
	def __repr__(self):
		return self._file

	def __str__(self):
		return self._abspath
	def __eq__(self,other):
		return self._abspath == str(other)
	def __ne__(self,other):
		return self._abspath != str(other)
	def delete(self):
		self._modified=True
		del self._root
		_deleted[self._abspath]=self
		for s in self._synonym:
			_loaded.pop(s)
	def readonly(self):
		return self._readonly
	def _removefromdisk(self):
		_os.remove(self._abspath)
		

def clearmodified(file):
	f=get(file)
	ret=f._modified
	f._modified=False
	return ret
def modified(file):
	get(file)._modified=True

def get(file):
	file=str(file)
	try:
		return _loaded[file]
	except:pass
	if file != '':
		abspath = _os.path.abspath(_os.path.realpath(file)).replace('\\', '/')
	else:
		abspath = ''
	try:
		# check if file is a synonym for a loaded file
		ret= _loaded[abspath]
		_loaded[file]=ret
		ret._synonym.add(file)
		return ret
	except: pass
	try:
		# check if file is a name on a file marked to be deleted
		ret=_deleted[abspath]
		del _deleted[abspath]
	except:
		ret=File(file,abspath)
	_loaded[abspath]=ret
	_loaded[ret._file]=ret
	ret._synonym={abspath,ret._file}
	return ret

def deleteallfiles():
	for file in tuple(_loaded.values()):
		file.delete()

def deleteondisk():
	for d in _deleted.values():
		d._removefromdisk()
	_deleted.clear()
